home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
amok_lha
/
amok77.lha
/
Funktionen
/
FunktionenPost.mod
< prev
next >
Wrap
Text File
|
1993-08-15
|
8KB
|
251 lines
(****************************************************************************
:Program. FunktionenPost.mod
:Contents. floating-point arithmetic compiler with postscript output
:Author. Richard Günther [gvm]
:Address. HeilbronnerStr.267, 7410 Reutlingen
:Phone. 07121/66432
:Copyright. Public Domain
:Language. Oberon
:Translator. AmigaOberon v2.14d
:History. V1.0 [gvm] 04-July-92 first implementation
:Bugs. none known
****************************************************************************)
(* Compiler Grammar:
Ausdruck = Summe.
Summe = Produkt {("+"|"-") Produkt}.
Produkt = Potenz {("*"|"/") Potenz}.
Potenz = Faktor {"^" Faktor}.
Faktor = ["+"|"-"](("(" Summe ")")|
(Funktion "(" Summe ")")|
Variable | Zahl | "pi" | "e").
Funktion = "SIN" | "COS" | "TAN" |....
Zahl = Ziffern["." Ziffern]["E"["+"|"-"] Ziffern].
Ziffern = Ziffer {Ziffer}.
Variable = CHAR. *)
MODULE FunktionenPost ;
IMPORT S : SYSTEM,
O : OberonLib,
E : Exec,
ST : Strings,
LRC : LongRealConversions ;
CONST Defs = "/e{2.718281828}def /pi{3.141592654}def /grad{57.29577951 mul}def /rad{0.01745329252 mul}def\n" ;
TYPE Func = STRUCT
name : ARRAY 8 OF CHAR ;
code : ARRAY 120 OF CHAR ;
END ;
FArrayTyp = ARRAY 15 OF Func ;
CONST FArray = FArrayTyp("ABS","abs\n",
"ACOS","dup dup mul 1 exch sub sqrt div atan rad\n",
"ASIN","dup dup mul 1 exch sub sqrt exch div atan rad\n",
"ATAN","atan rad\n",
"COS","grad cos\n",
"COSH","dup e exch exp exch neg e exch exp add 2 div\n",
"EXP","e exch exp\n",
"LN","ln\n",
"LOG","log\n",
"SIN","grad sin\n",
"SINH","dup e exch exp exch neg e exch exp sub 2 div\n",
"SQRT","sqrt\n",
"TAN","dup grad sin exch grad cos div\n",
"TANH","dup dup e exch exp exch neg e exch exp sub exch dup e exch exp exch neg e exch exp add div\n",
"",""
) ;
PROCEDURE Compile*( source : ARRAY OF CHAR ;
vars : ARRAY OF CHAR ; (* z.B. "xy" *)
funcName : ARRAY OF CHAR ;
VAR code : ARRAY OF CHAR ;
VAR errpos : INTEGER): BOOLEAN ;
VAR pos,len : INTEGER ;
cLen,maxCLen : INTEGER ;
numVars : INTEGER ;
i : INTEGER ;
notEmpty : BOOLEAN ;
PROCEDURE PutChar(char : CHAR): BOOLEAN ;
BEGIN
INC(cLen,1) ;
IF cLen>=maxCLen THEN errpos:=-2 ; RETURN TRUE END ;
ST.AppendChar(code,char) ;
notEmpty:=TRUE ; RETURN FALSE ;
END PutChar ;
(* $CopyArrays- *)
PROCEDURE Put(string : ARRAY OF CHAR): BOOLEAN ;
BEGIN
INC(cLen,ST.Length(string)) ;
IF cLen>=maxCLen THEN errpos:=-2 ; RETURN TRUE END ;
ST.Append(code,string) ;
notEmpty:=TRUE ; RETURN FALSE ;
END Put ;
PROCEDURE Fehler ;
BEGIN
IF errpos=-1 THEN errpos:=pos ; pos:=256 END ;
END Fehler ;
PROCEDURE Match(c : CHAR):BOOLEAN ;
BEGIN
IF source[pos]=c THEN INC(pos) ; RETURN FALSE
ELSE Fehler ; RETURN TRUE
END ;
END Match ;
PROCEDURE SkipBlanks ;
BEGIN
WHILE (pos<=len) AND (source[pos]=" ") DO INC(pos) END ;
END SkipBlanks ;
PROCEDURE ^Summe(): BOOLEAN ;
PROCEDURE ReadZiffern():BOOLEAN ;
BEGIN
IF (pos>len) OR ((source[pos]<"0") OR (source[pos]>"9")) THEN
Fehler ; RETURN TRUE END ;
WHILE (pos<=len) AND ((source[pos]>="0") AND (source[pos]<="9")) DO
INC(pos) END ;
RETURN FALSE ;
END ReadZiffern ;
PROCEDURE Zahl(negativ: BOOLEAN): BOOLEAN ;
VAR start: INTEGER ;
buf : ARRAY 32 OF CHAR ;
lr: LONGREAL ;
BEGIN
start:=pos ;
IF ReadZiffern() THEN RETURN TRUE END ;
IF (pos<=len) AND (source[pos]=".") THEN
INC(pos) ; IF ReadZiffern() THEN RETURN TRUE END ;
END ;
IF (pos<=len) AND (source[pos]="E") THEN
INC(pos) ;
IF (pos<=len) AND ((source[pos]="+") OR (source[pos]="-")) THEN
INC(pos) ; END ;
IF ReadZiffern() THEN RETURN TRUE END ;
END ;
IF negativ THEN DEC(start) END ;
ST.Cut(source,start,pos-start,buf) ;
IF ~LRC.StringToReal(buf,lr)
OR Put(buf) OR Put(" ") THEN RETURN TRUE END ;
RETURN FALSE
END Zahl ;
PROCEDURE Faktor():BOOLEAN ;
VAR negieren : BOOLEAN ;
token : ARRAY 8 OF CHAR ;
tpos : INTEGER ;
BEGIN
SkipBlanks ;
negieren:=(pos<=len) AND (source[pos]="-") ;
IF (pos<=len) AND ((source[pos]="+") OR (source[pos]="-")) THEN
INC(pos)
END ;
IF (pos<=len) THEN
CASE source[pos] OF
"0".."9": IF Zahl(negieren) THEN RETURN TRUE END ;
negieren:=FALSE |
"(": INC(pos) ;
IF Summe() OR Match(")") THEN RETURN TRUE END |
ELSE
tpos:=0 ;
WHILE (source[pos]>="A") AND (source[pos]<="Z") DO
token[tpos]:=source[pos] ; INC(tpos) ; INC(pos) ;
END ;
token[tpos]:=CHR(0) ;
tpos:=0 ;
LOOP
WHILE FArray[tpos].name#"" DO
IF token=FArray[tpos].name THEN
IF Match("(") OR Summe() OR Match(")")
OR Put(FArray[tpos].code) THEN RETURN TRUE END ;
EXIT ;
END ;
INC(tpos) ;
END ;
IF token="PI" THEN IF Put("pi ") THEN RETURN TRUE END ;
ELSIF token="E" THEN IF Put("e ") THEN RETURN TRUE END ;
ELSIF token[1]=CHR(0) THEN
tpos:=0 ;
WHILE tpos#numVars DO
IF vars[tpos]=token[0] THEN
IF PutChar(vars[tpos]) OR Put(" ") THEN RETURN TRUE END ;
EXIT ;
END ;
INC(tpos) ;
END ;
Fehler ;
ELSE Fehler ; RETURN TRUE
END ;
EXIT ;
END ;
END ;
END ;
IF negieren THEN IF Put("neg ") THEN RETURN TRUE END ;
END ;
SkipBlanks ;
RETURN FALSE ;
END Faktor ;
PROCEDURE Potenz(): BOOLEAN ;
BEGIN
IF Faktor() THEN RETURN TRUE END ;
WHILE (pos<=len) AND (source[pos]="^") DO
INC(pos) ;
IF Faktor() OR Put("exp ") THEN RETURN TRUE END ;
END ;
RETURN FALSE ;
END Potenz ;
PROCEDURE Produkt(): BOOLEAN ;
VAR ch : CHAR ;
BEGIN
IF Potenz() THEN RETURN TRUE END ;
WHILE (pos<=len) AND ((source[pos]="*") OR (source[pos]="/")) DO
ch:=source[pos] ; INC(pos) ;
IF Potenz() THEN RETURN TRUE END ;
IF ch="*" THEN IF Put("mul ") THEN RETURN TRUE END ;
ELSE IF Put("div ") THEN RETURN TRUE END ;
END ;
END ;
RETURN FALSE ;
END Produkt ;
PROCEDURE Summe(): BOOLEAN ;
VAR ch : CHAR ;
BEGIN
IF Produkt() THEN RETURN TRUE END ;
WHILE (pos<=len) AND ((source[pos]="+") OR (source[pos]="-")) DO
ch:=source[pos] ; INC(pos) ;
IF Produkt() THEN RETURN TRUE END ;
IF ch="+" THEN IF Put("add\n") THEN RETURN TRUE END ;
ELSE IF Put("sub\n") THEN RETURN TRUE END ;
END ;
END ;
END Summe ;
BEGIN
ST.Upper(source) ; len:=ST.Length(source) ;
ST.Upper(vars) ; numVars:=ST.Length(vars) ;
maxCLen:=LEN(code) ; cLen:=0 ; code:="" ;
IF len=0 THEN RETURN FALSE END ;
pos:=0 ; errpos:=-1 ;
IF Put("/") OR Put(funcName) OR Put("{\n")
OR Put(Defs) THEN RETURN FALSE END ;
i:=numVars-1 ;
WHILE i>-1 DO
IF Put("/") OR PutChar(vars[i]) OR Put(" exch def\n") THEN RETURN FALSE END ;
DEC(i) ;
END ;
notEmpty:=FALSE ;
IF Summe() OR ~notEmpty OR Put("} def\n") THEN RETURN FALSE END ;
RETURN TRUE ;
END Compile ;
END FunktionenPost.